package com.fjx.sortdemo.service;

import com.fjx.sortdemo.entity.req.SortReq;
import com.fjx.sortdemo.entity.resp.SortResp;
import com.google.common.collect.Lists;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class SortHandlerService {
    public List<SortResp> sortHandler(SortReq sortReq) {
        List<SortResp> sortRespList = sortReq.getSortRespList();
        if (!CollectionUtils.isEmpty(sortReq.getSortItemList())) {
            SortReq.SortItem sortItem = sortReq.getSortItemList().stream().findFirst().get();
            if (sortReq.getSortItemList().size() == 1) {
                //todo 还查标签类型的排序
                if (sortItem.getSortCol().equals("date")) {
                    return sortRespList.stream()
                            .sorted((a, b) -> {
                                int result = a.getDate().compareTo(b.getDate());
                                return "asc".equalsIgnoreCase(sortItem.getSortOrder()) ? result : -result;
                            })
                            .collect(Collectors.toList());
                } else if (sortItem.getSortCol().equals("name")) {
                    return sortWithChineseEnglishMixed(sortRespList, SortResp::getName, sortItem.getSortOrder());
                }
            }
            //todo 还差多列混排
        }
        return sortRespList;
    }

    /**
     * 通用中英文混合排序方法
     *
     * @param list        待排序列表
     * @param fieldGetter 获取排序字段的函数
     * @param sortOrder   排序顺序 ("asc"或"desc")
     * @param <T>         列表元素类型
     * @param <R>         排序字段类型(必须为String)
     * @return 排序后的列表
     */
    public <T, R extends String> List<T> sortWithChineseEnglishMixed(
            List<T> list,
            Function<T, R> fieldGetter,
            String sortOrder) {

        if (CollectionUtils.isEmpty(list)) {
            return list;
        }

        // 提取排序字段值
        List<String> fieldValueList = list.stream()
                .map(fieldGetter)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        // 分离英文和中文
        List<String> englishStrList = fieldValueList.stream()
                .filter(str -> !StringUtils.isEmpty(str) && isEnglish(str.charAt(0)))
                .sorted(this::compareMixedStrings)
                .collect(Collectors.toList());

        List<String> chinaStrList = fieldValueList.stream()
                .filter(str -> !StringUtils.isEmpty(str) && !isEnglish(str.charAt(0)))
                .sorted(this::compareMixedStrings)
                .collect(Collectors.toList());

        // 处理排序顺序
        if ("desc".equalsIgnoreCase(sortOrder)) {
            Collections.reverse(englishStrList);
            Collections.reverse(chinaStrList);
        }

        // 合并结果
        List<String> sortedFieldValues = new ArrayList<>();
        sortedFieldValues.addAll(englishStrList);
        sortedFieldValues.addAll(chinaStrList);

        // 按排序后的字段值重新组织原始对象
        Map<String, List<T>> valueMap = list.stream()
                .collect(Collectors.groupingBy(fieldGetter));
//去重可能有bug
        return sortedFieldValues.stream()
                .map(valueMap::get)
                .filter(Objects::nonNull)
                .flatMap(List::stream)
                .distinct()
                .collect(Collectors.toList());
    }


    // 自定义中英文混合排序规则，英文字符始终排在前面
    private int compareMixedStrings(String str1, String str2) {
        // 处理空字符串
        if (StringUtils.isEmpty(str1) && StringUtils.isEmpty(str2)) {
            return 0;
        }
        if (StringUtils.isEmpty(str1)) {
            return 1; // str1 为空，排在最后
        }
        if (StringUtils.isEmpty(str2)) {
            return -1; // str2 为空，排在最后
        }

        // 获取首字母
        char c1 = str1.charAt(0);
        char c2 = str2.charAt(0);

        // 判断字符是否为英文
        boolean isEnglish1 = isEnglish(c1);
        boolean isEnglish2 = isEnglish(c2);

        // 英文直接比较
        if (isEnglish1 && isEnglish2) {
            return Character.compare(c1, c2);
        }
        //中文按照拼音首字母排序
        else if (!isEnglish1 && !isEnglish2) {
            String pinyin1 = getPinyinInitial(str1);
            String pinyin2 = getPinyinInitial(str2);
            return Character.compare(pinyin1.charAt(0), pinyin2.charAt(0));
        }
        // 英文排在非英文之前
        return isEnglish1 ? -1 : 1;
    }

    // 获取字符串的拼音首字母
    private String getPinyinInitial(String str) {
        char firstChar = str.charAt(0);
        // 将中文转换为拼音首字母
        String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(firstChar);
        return String.valueOf(pinyinArray[0].charAt(0));

    }

    // 判断字符是否为英文
    private boolean isEnglish(char c) {
        return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
    }
}
